import { ImageResponse } from 'next/og'; import { t } from '@/i18n'; import { safe } from '@/lib/api'; import { apiExplore } from '@/lib/api-explore'; import { formatValue } from '@/lib/format'; import { OG_INK2, OG_INK3, OG_RULE, OG_SIZE_H, OG_SIZE_W, OgFrame, OgWordmark } from '../../og-shared'; export const alt = 'Indicator by country on CountryAtlas'; export const size = { width: OG_SIZE_W, height: OG_SIZE_H }; export const contentType = 'image/png'; export const revalidate = 3600; /** Light→dark sequential ramp (globals.css --seq-1…7, light theme) — Satori needs literal colours. */ const SEQ = ['#cde2fb', '#9ec5f4', '#6da7ec', '#3987e5', '#256abf', '#184f95', '#0d366b']; /** Per-indicator social image: name, world value + kind, year, coverage, mini sequential legend. */ export default async function IndicatorOgImage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params; const data = await safe(apiExplore.indicator(slug)); const ind = data?.indicator; const name = ind?.name ?? slug.replace(/-/g, ' '); const wl = data?.world_latest ?? null; const kind = wl ? (wl.kind === 'sum' ? 'World total' : wl.kind === 'weighted_mean' ? 'World average' : 'World median') : null; const sub = [ind?.unit, ind?.topic ? ind.topic.replace(/-/g, ' ') : null].filter(Boolean).join(' · '); const coverage = data ? `${data.coverage.n_countries ?? 0} countries · ${data.years.first ?? ''}–${data.years.last_actual ?? ''}` : ''; return new ImageResponse( (
{t('common.indicator')}
40 ? 52 : 64, fontWeight: 600, letterSpacing: -1.5, lineHeight: 1.05, marginTop: 8 }}>{name}
{sub ?
{sub}
: null}
{wl && ind && wl.value != null ? (
{kind}
{formatValue(wl.value, ind)}
{`${wl.year ?? ''}${coverage ? ` · ${coverage}` : ''}`}
) : (
{coverage || 'World map, trend, ranking and sources'}
)}
{SEQ.map((c) => (
))}
low high
{t('og.site')}
), { ...size }, ); }